#python
#1、python解释器有哪些？ cpython和pypy的区别是什么？
    #区别：参考https://www.cnblogs.com/huangjiangyong/p/14108754.html
    # python解释器
    # cpython  c语言
    # jpython  java
    # ipython  交互式解释器
    # Ironpython  c#
    # pypy  Rpython#
    # cpython  官方支持的库多
    # pypy  速度快  --jit



#2、python2和python3的区别是什么？列举出7个
#       print函数 2是语句 3是函数
#       整数相除 2是整数 3是浮点
#       Unicode 2为str Unicode 3只有Unicode
#       异常处理 3强制 except ZeroDivisionError as e:的写法
#       xrange 3不支持xrange
#       map函数 2map返回list 3map返回iterator
#       不支持has_key


#3、python中list和set的区别是什么
#列表(list) 有序 是可变数据类型 可重复
#集合(set) 无序 集合元素必须是可变数据类型 去重 只接受可hash对象


#4、python装饰器用来做什么？写过什么装饰器？两层装饰器和三层装饰器区别         装饰器可以装饰哪些内容
    # 不改变函数或者类的源代码的基础上，添加额外功能
    # 统计运行时间的装饰器 记录日志执行操作 判断函数运行前是否有权限
    # 自身不传入参数的装饰器，使用两层函数定义;自身传入参数的装饰器，使用三层函数定义
    # 类和函数


#5、python的list底层使用什么实现，怎么实现扩容，字典底层原理
    # 底层是数组
    # (1)当旧的底层数组存满时，list类会自动请求一个新的容量为旧的数组两倍的新数组
    # (2)旧数组中元素将被一次存入新的数组
    # (3)系统回收旧的数组，并初始化新数组
    # Python字典的底层实现是哈希表，元素以键值对的形式存在

#6、yiled关键字有什么作用，迭代器有什么作用，生成器的使用场景有哪些
    # 返回数值作用，但是 yield 会记住当下的值，再次调用时，从使用 yield 的下一行继续运行
    # 迭代器是一个对象，用于迭代列表、元组、字典和集合等可迭代对象
    # 大文件的读取


#7、异常捕获主要用在哪些地方，有什么用，使用语句结构， 常见的异常类有哪些
    # 如果异常未捕捉，系统就会一直将异常传递下去，直到程序由于异常而异常而中断。
    # 为了避免出现这种程序异常中断的情况，现在对的代码段进行异常捕捉
    # try:
    #     print("test...")
    #     # 1/0
    #     int("abc")
    # except ZeroDivisionError:
    #     print("error")
    # else:
    #     print("else test...")
    # finally:
    #     print("finally test...")
    # NameError 访问未声明变量
    # ZeroDivisionError 除数为0
    # IndexError 下标异常
    # KeyError 关键字异常
    # AttributeError属性异常
    # ValueError传参异常
    # AssertionError断言异常


#8、变量名的解析按照什么顺序
    # 1、先从本地命名空间查找Local
	# 2、任意上层函数作用域 Enclosing
	# 3、在全局作用域 Global
	# 4、最后在内置作用域中查找 Built-in

#9、python的模块查找顺序是什么， 相对导入和绝对导入区别在哪里
    # 1.查看当前程序里面已经加载好的模块
    # 2.没有加载到内存的模块通过sys.path的路径一个一个去找

    # 相对导入 以.开头的模块包名
    # 绝对导入就是从top-level 开始一层一层往下数导入


#10、__name__变量值是什么，有什么用？ __file__变量存储什么内容
    # __main__,当Python程序直接运行时，__name__变量的值是字符串 __main__,或者输出模块名
    # 当前.py文件的绝对路径


#11、什么是魔术方法？使用过什么魔术方法？
    # 在python中所有以__开头和结尾的方法，统称为魔术方法（magic method）;这种魔术方法不需要调用，在特定场景下自动执行，普通方法需要程序员调用
    # __new__创建实例
    # __init__实例初始化
    # 析构函数（__del__）
    # 调用方法（__call__）
    # __str__ __repr__
    # 返回对象的描述信息
    # __getitem__
    # __setitem__
    # __delitem__

#12、面向对象 python3使用什么继承算法？
    # c3继承算法

#13、打包过python模块包吗？ 有没有去了解过如何打包python模块
    # 模块打包与发布
    # 1.创建一个目录modpack，创建空文件__init__.py
    # 2.在modpack下创建模块
    # [root@localhost modpack]# ls
    # __init__.py
    # [root@localhost modpack]# vim mod.py
    # [root@localhost modpack]# cat mod.py
    # def func():
    #     print("i am modpack function")
    # 3.回到modpack同级目录，创建setup.py文件
    # [root@localhost lianxi]# vim setup.py
    # [root@localhost lianxi]# cat setup.py
    # from setuptools import setup, find_packages
    #
    # setup(
    #     #包名
    #     name = "modtest",
    #     #官网
    #     url = "http://www.abc.com",
    #     #版本
    #     version = "0.0.1",
    #     #指定要打包的模块和包
    #     packages = find_packages(),
    #     #作者
    #     author = "sc",
    #     #邮箱
    #     author_email = "123456@qq.com",
    #     #依赖
    #     install_requires = ['xlrd>=1.1.0'],
    #     #描述信息
    #     description = "this is test pack"
    # )




#14、python中如何使用正则表达式，怎么表示空行，怎么表示以#开头的行？         hello world, "test123 sc"  如何将这里面的单词字符挨个提取出来，引号包裹的算一个单词字符
    # re模块；
    # ^$
    # r#^

    # import re
    # for line in open("test.txt"):
    #     line = line.strip('\n')
    #     regex = re.compile('^#')
    #     m = re.match(regex,line)
    #     if m is not None:
    #         print(line)

    # import re
    # string = 'hello world, "test123 sc"'
    # print([m[1] for m in re.findall(r'(["\'])?((?(1).*?\1|\w+))', string)])



#15、使用python实现队列
# class Queue():
#     def __init__(self):
#         self.items = []
#     def enqueue(self,item):
#         self.items.insert(0,item)
#     def dequeue(self):
#         return self.items.pop()
#     def size(self):
#         return len(self.items)

#16、使用python实现tree命令
# import os
# def tree(path,depth=0):
#     if depth == 0:
#         print(path)
#     for item in os.listdir(path):
#         print("|    "*depth,end="")
#         print("|----",item)
#         item = os.path.join(path,item)
#         if os.path.isdir(item):
#             tree(item,depth+1)
#17、爬取新浪官网的图片


# -*- conding:utf-8 -*-
import requests
import re
import os
#需求：爬取某体育中图片信息
if __name__ == "__main__":
    #判断系统是否存在文件夹，没有文件夹自行创建。
    if not os.path.exists('./gitPicture'):
        os.mkdir('./gitPicture')
    #检查图片地址
    url = 'http://sports.sina.com.cn/'
    #伪装浏览器
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 '}
    #text(字符串)，content（二进制）json(对象)
    picture_data = requests.get(url=url,headers=headers).text
    #使用聚焦爬虫将页面中所有的新浪图片进行解析/提取，使用正则表达式匹配字符。 .是匹配任意字符，#匹配前面字符出现多次，？匹配前面字符出现一次或者零次
    ex = 'height: 236px;">.*?<img src="(.*?)" alt.*? '
    #使用正则表达式函数匹配，用re.S进行换行搜索
    image_src_list = re.findall(ex,picture_data,re.S)
    #使用for循环从列表中抽取每个图片数据，进行命名保存。
    for src in image_src_list:
        img = src
        image_data = requests.get(url=img,headers=headers).content
        image_name = img.split('/')[-1]
        image_Path = './gitPicture/'+image_name
        #本地化存储到对应文件夹中
        with open(image_Path,'wb') as fp:
            fp.write(image_data)
            print(image_name,'下载成功！！！')

#18、python的内存管理，深浅拷贝的区别
    # 深浅拷贝
    # 容器类型里面包可变数据类型的时候，深浅拷贝会造成不同的影响
    # 浅拷贝之后的数据改变可能会影响原来的数据
    # 深拷贝之后的数据不会影响原来的数据
    # 浅拷贝只拷贝容器类型第一层数据的地址
    # 深拷贝会拷贝容器类型每一层数据的地址

#19、python中文件操作？如何删除文件，创建文件，写入文件，读取文件

    # 创建文件，创建一个名为aa.txt的文件
    # open("aa.txt",'w')
    #
    # os.remove('aa.txt')

    # fp = open("test.txt","wb")
    # fp.write(b"hellow\n")
    # fp.close()

    # with open("example.txt",encoding="utf8") as fp:
    #     print(fp.read()) #读全文`

#20、assert关键的作用是什么
# 断言，当这个关键字后边的条件为假的时候，程序结束
